package controller

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"
	"strings"
	"time"

	"gitee.com/wangshh_123/cross-pay-go/src/models"
	"gitee.com/wangshh_123/cross-pay-go/src/platform/providers/photonpay"
	"gitee.com/wangshh_123/cross-pay-go/src/service"
	"gitee.com/wangshh_123/cross-pay-go/src/utils/common"

	"log"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"gorm.io/gorm"
)

// AccountController 账号控制器
type AccountController struct {
	accountService      *service.AccountService
	notificationService *service.NotificationService
	db                  *gorm.DB
	photonPayClient     *photonpay.PhotonPayClient
}

// NewAccountController 创建账号控制器实例
func NewAccountController(photonPayClient *photonpay.PhotonPayClient) *AccountController {
	return &AccountController{
		accountService:      service.NewAccountService(),
		notificationService: service.NewNotificationService(),
		db:                  service.GetDB(),
		photonPayClient:     photonPayClient,
	}
}

// 辅助函数：获取并验证主账号
func (c *AccountController) getAndValidateMasterAccount(ctx *gin.Context) (*models.MasterAccount, bool) {
	userID, exists := ctx.Get("user_id")
	if !exists {
		common.Error(ctx, http.StatusUnauthorized, "unauthorized", nil)
		return nil, false
	}

	masterAccount, err := c.accountService.GetMasterAccount(userID.(int64))
	if err != nil {
		if strings.Contains(err.Error(), "master_account_not_found") {
			common.Error(ctx, http.StatusNotFound, "master_account_not_found", err)
		} else {
			common.Error(ctx, http.StatusInternalServerError, "error", err)
		}
		return nil, false
	}

	if masterAccount.UserID != userID.(int64) {
		common.Error(ctx, http.StatusForbidden, "forbidden", nil)
		return nil, false
	}

	return masterAccount, true
}

// CreateMasterAccount 创建主账号
func (c *AccountController) CreateMasterAccount(ctx *gin.Context) {
	userID, ok := service.GetCurrentUserID(ctx)
	if !ok {
		return
	}

	var req struct {
		AccountName string `json:"account_name" binding:"required"`
		AccountType string `json:"account_type" binding:"required,oneof=enterprise individual"`
	}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_params", err)
		return
	}

	masterAccount, err := c.accountService.CreateMasterAccount(userID, req.AccountName, req.AccountType)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "error", err)
		return
	}

	// 同步光子易余额
	service.SyncPhotonPayBalance(ctx, c.db, c.photonPayClient, userID, masterAccount.ID)

	// 赋予主账号角色（role_id=3，假设3是master_user），通过 UserService
	userService := service.NewUserService()
	err = userService.AssignRoleToUser(userID, 3)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "assign_role_failed", err)
		return
	}

	common.Success(ctx, gin.H{
		"message": "account_create_success",
		"data":    masterAccount,
	})
}

// GetMasterAccount 获取主账号信息
func (c *AccountController) GetMasterAccount(ctx *gin.Context) {
	masterAccount, ok := c.getAndValidateMasterAccount(ctx)
	if !ok {
		return
	}

	common.Success(ctx, gin.H{
		"message": "success",
		"data":    masterAccount,
	})
}

// UpdateMasterAccount 更新主账号信息
func (c *AccountController) UpdateMasterAccount(ctx *gin.Context) {
	masterAccount, ok := c.getAndValidateMasterAccount(ctx)
	if !ok {
		return
	}

	var req struct {
		AccountName string `json:"account_name" binding:"required"`
		AccountType string `json:"account_type" binding:"required,oneof=enterprise individual"`
	}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_params", err)
		return
	}

	// 更新主账号信息
	masterAccount.AccountName = req.AccountName
	masterAccount.AccountType = req.AccountType

	if err := c.accountService.UpdateMasterAccount(masterAccount); err != nil {
		common.Error(ctx, http.StatusInternalServerError, "error", err)
		return
	}

	common.Success(ctx, gin.H{
		"message": "account_update_success",
	})
}

// CreateSubAccount 生成子账号邀请码
func (c *AccountController) CreateSubAccount(ctx *gin.Context) {
	userID, ok := service.GetCurrentUserID(ctx)
	if !ok {
		return
	}

	// 解析请求参数
	var req struct {
		AccountName string                 `json:"account_name" binding:"required"`
		Role        string                 `json:"role" binding:"required,oneof=user masterUser subUser"`
		Permissions map[string]interface{} `json:"permissions" binding:"required"`
	}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": "参数错误"})
		return
	}

	// 生成邀请码
	invitationCode, err := c.accountService.GenerateInvitationCode(
		userID,
		req.AccountName,
		req.Role,
		req.Permissions,
		24*time.Hour,
	)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "邀请码生成成功",
		"data": gin.H{
			"invitation_code": invitationCode,
			"expire_time":     "24h",
			"usage_limit":     "1",
			"account_name":    req.AccountName,
			"role":            req.Role,
			"permissions":     req.Permissions,
		},
	})
}

// GetSubAccount 获取子账号信息
func (c *AccountController) GetSubAccount(ctx *gin.Context) {
	id, ok := service.ParsePathID(ctx, "id")
	if !ok {
		return
	}

	subAccount, err := c.accountService.GetSubAccount(id)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	ctx.JSON(http.StatusOK, subAccount)
}

// UpdateSubAccount 更新子账号信息
func (c *AccountController) UpdateSubAccount(ctx *gin.Context) {
	id, ok := service.ParsePathID(ctx, "id")
	if !ok {
		return
	}

	var req struct {
		AccountName string                 `json:"account_name" binding:"required"`
		Role        string                 `json:"role" binding:"required,oneof=user masterUser subUser"`
		Permissions map[string]interface{} `json:"permissions" binding:"required"`
	}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_params", err)
		return
	}

	// 将权限对象转换为JSON字符串
	permissionsJSON, err := json.Marshal(req.Permissions)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_permissions_format", err)
		return
	}

	if err := c.accountService.UpdateSubAccount(id, req.AccountName, req.Role, string(permissionsJSON)); err != nil {
		common.Error(ctx, http.StatusInternalServerError, "update_sub_account_failed", err)
		return
	}

	common.Success(ctx, gin.H{
		"message": "account_update_success",
	})
}

// DeleteSubAccount 删除子账号
func (c *AccountController) DeleteSubAccount(ctx *gin.Context) {
	// 获取当前用户ID
	userID, ok := service.GetCurrentUserID(ctx)
	if !ok {
		return
	}

	// 获取当前用户的主账户
	masterAccount, err := c.accountService.GetMasterAccount(userID)
	if err != nil {
		common.Error(ctx, http.StatusNotFound, "master_account_not_found", err)
		return
	}

	id, ok := service.ParsePathID(ctx, "id")
	if !ok {
		return
	}

	// 获取子账号信息
	sub, err := c.accountService.GetSubAccount(id)
	if err != nil {
		common.Error(ctx, http.StatusNotFound, "sub_account_not_found", err)
		return
	}

	// 验证子账户是否属于当前用户的主账户
	if sub.MasterAccountID != masterAccount.ID {
		common.Error(ctx, http.StatusForbidden, "sub_account_not_belong_to_master", nil)
		return
	}

	// 执行退款和删除操作
	err = c.accountService.RefundAndDeleteSubAccount(sub.MasterAccountID, id, "子账号销户退还")
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "refund_and_delete_failed", err)
		return
	}

	common.Success(ctx, gin.H{
		"message": "account_delete_success",
	})
}

// GetSubAccountsByMasterID 获取主账号下的所有子账号
func (c *AccountController) GetSubAccountsByMasterID(ctx *gin.Context) {
	masterAccount, ok := c.getAndValidateMasterAccount(ctx)
	if !ok {
		return
	}

	// 获取分页参数
	page, pageSize := common.GetPaginationParams(ctx)

	// 获取查询参数
	username := ctx.Query("username")
	role := ctx.Query("role")
	status := ctx.Query("status")

	// 构建查询条件
	conditions := make(map[string]interface{})
	if username != "" {
		conditions["username"] = username
	}
	if role != "" {
		conditions["role"] = role
	}
	if status != "" {
		conditions["status"] = status
	}

	// 调用服务方法获取分页数据
	subAccounts, total, err := c.accountService.GetSubAccountsWithConditions(masterAccount.ID, conditions, int(page), int(pageSize))
	if err != nil {
		if strings.Contains(err.Error(), "sub_account_not_found") {
			common.Error(ctx, http.StatusNotFound, "sub_account_not_found", err)
		} else {
			common.Error(ctx, http.StatusInternalServerError, "error", err)
		}
		return
	}

	// 计算分页信息
	totalPages := (total + int64(pageSize) - 1) / int64(pageSize)

	common.Success(ctx, gin.H{
		"list":        subAccounts,
		"total":       total,
		"page":        page,
		"page_size":   pageSize,
		"total_pages": totalPages,
	})
}

// UpdateSubAccountStatus 更新子账号状态
func (c *AccountController) UpdateSubAccountStatus(ctx *gin.Context) {
	// 获取当前用户ID
	userID, ok := service.GetCurrentUserID(ctx)
	if !ok {
		return
	}

	// 获取当前用户的主账户
	masterAccount, err := c.accountService.GetMasterAccount(userID)
	if err != nil {
		common.Error(ctx, http.StatusNotFound, "master_account_not_found", err)
		return
	}

	id, ok := service.ParsePathID(ctx, "id")
	if !ok {
		return
	}

	// 获取子账户信息并验证权限
	subAccount, err := c.accountService.GetSubAccount(id)
	if err != nil {
		common.Error(ctx, http.StatusNotFound, "sub_account_not_found", err)
		return
	}

	// 验证子账户是否属于当前用户的主账户
	if subAccount.MasterAccountID != masterAccount.ID {
		common.Error(ctx, http.StatusForbidden, "sub_account_not_belong_to_master", nil)
		return
	}

	var req struct {
		Status string `json:"status" binding:"required,oneof=normal frozen"`
	}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_params", err)
		return
	}

	if err := c.accountService.UpdateSubAccountStatus(id, req.Status); err != nil {
		common.Error(ctx, http.StatusInternalServerError, "update_sub_account_status_failed", err)
		return
	}

	common.Success(ctx, gin.H{
		"message": "account_status_updated",
	})
}

// POST /master-accounts/:cate-balance
func (c *AccountController) AllocateBalance(ctx *gin.Context) {
	masterAccount, ok := c.getAndValidateMasterAccount(ctx)
	if !ok {
		return
	}

	var req struct {
		SubAccountID  int64   `json:"sub_account_id"`
		Amount        float64 `json:"amount"`
		Remark        string  `json:"remark"`
		OperationType string  `json:"operation_type" binding:"required,oneof=IN OUT"`
	}
	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_params", err)
		return
	}

	// 获取子账户信息
	subAccount, err := c.accountService.GetSubAccount(req.SubAccountID)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "get_sub_account_failed", err)
		return
	}

	// 验证子账户是否属于当前用户的主账户
	if subAccount.MasterAccountID != masterAccount.ID {
		common.Error(ctx, http.StatusForbidden, "sub_account_not_belong_to_master", nil)
		return
	}

	// 根据操作类型设置金额正负
	amount := req.Amount
	if req.OperationType == "OUT" {
		amount = -amount
	}

	// 设置资金划分类型
	fundType := "allocate"
	if req.OperationType == "OUT" {
		fundType = "refund"
	}

	// 执行划拨
	err = c.accountService.AllocateBalance(masterAccount.ID, req.SubAccountID, amount, req.Remark, fundType)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "allocate_balance_failed", err)
		return
	}

	// 生成交易流水号
	transactionID := uuid.New().String()

	// 创建通知
	notificationData := map[string]interface{}{
		"account_name":   masterAccount.AccountName,
		"transaction_id": transactionID,
		"operation_type": req.OperationType,
		"amount":         fmt.Sprintf("%.2f", amount),
	}

	if req.OperationType == "IN" {
		err = c.notificationService.PublishSystemNotification(ctx, subAccount.UserID, "余额转入",
			fmt.Sprintf("您的账户收到转入金额 %.2f", amount), notificationData)
	} else {
		err = c.notificationService.PublishSystemNotification(ctx, subAccount.UserID, "余额转出",
			fmt.Sprintf("您的账户转出金额 %.2f", amount), notificationData)
	}

	if err != nil {
		log.Printf("发送通知失败: %v", err)
		// 通知发送失败不影响主流程，所以只记录日志
	}

	common.Success(ctx)
}

func (c *AccountController) SubAccountConsume(ctx *gin.Context) {
	// 获取当前用户ID
	userID, ok := service.GetCurrentUserID(ctx)
	if !ok {
		return
	}

	// 获取当前用户的主账户
	masterAccount, err := c.accountService.GetMasterAccount(userID)
	if err != nil {
		common.Error(ctx, http.StatusNotFound, "master_account_not_found", err)
		return
	}

	var req struct {
		SubAccountID int64   `json:"sub_account_id"`
		Amount       float64 `json:"amount"`
		Remark       string  `json:"remark"`
	}
	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_params", err)
		return
	}

	// 获取子账户信息
	subAccount, err := c.accountService.GetSubAccount(req.SubAccountID)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "get_sub_account_failed", err)
		return
	}

	// 验证子账户是否属于当前用户的主账户
	if subAccount.MasterAccountID != masterAccount.ID {
		common.Error(ctx, http.StatusForbidden, "sub_account_not_belong_to_master", nil)
		return
	}

	err = c.accountService.SubAccountConsume(req.SubAccountID, req.Amount, req.Remark)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "consume_failed", err)
		return
	}
	common.Success(ctx)
}

// GetMasterSubAccountFunds 获取主账号资金划拨明细
func (c *AccountController) GetMasterSubAccountFunds(ctx *gin.Context) {
	masterAccount, ok := c.getAndValidateMasterAccount(ctx)
	if !ok {
		return
	}

	// 获取分页参数
	page, pageSize := common.GetPaginationParams(ctx)

	// 获取查询参数
	queryType := ctx.Query("type")                  // 获取 type 参数
	subAccountIDStr := ctx.Query("sub_account_id")  // 获取 sub_account_id 参数
	subAccountName := ctx.Query("sub_account_name") // 获取 sub_account_name 参数
	createdAtStart := ctx.Query("created_at_start") // 获取 created_at 开始时间
	createdAtEnd := ctx.Query("created_at_end")     // 获取 created_at 结束时间

	// 处理 sub_account_id 参数
	var subID int64
	if subAccountIDStr != "" {
		var err error
		subID, err = strconv.ParseInt(subAccountIDStr, 10, 64)
		if err != nil {
			common.Error(ctx, http.StatusBadRequest, "invalid_sub_account_id", err)
			return
		}

		// 验证子账号是否属于当前主账号
		subAccount, err := c.accountService.GetSubAccount(subID)
		if err != nil {
			common.Error(ctx, http.StatusNotFound, "sub_account_not_found", err)
			return
		}

		if subAccount.MasterAccountID != masterAccount.ID {
			common.Error(ctx, http.StatusForbidden, "sub_account_not_belong_to_master", nil)
			return
		}
	}

	// 获取资金划拨记录
	funds, total, err := c.accountService.GetMasterSubAccountFunds(masterAccount.ID, int(page), int(pageSize), queryType, subID, subAccountName, createdAtStart, createdAtEnd)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_funds_failed", err)
		return
	}

	common.Success(ctx, gin.H{
		"total": total,
		"data":  funds,
		"query_params": gin.H{
			"type":             queryType,
			"sub_account_id":   subAccountIDStr,
			"sub_account_name": subAccountName,
			"created_at_start": createdAtStart,
			"created_at_end":   createdAtEnd,
		},
	})
}

// GetSubAccountConsumeRecords 获取子账号消费记录
func (c *AccountController) GetSubAccountConsumeRecords(ctx *gin.Context) {
	userID, ok := service.GetCurrentUserID(ctx)
	if !ok {
		return
	}

	subID, ok := service.ParsePathID(ctx, "id")
	if !ok {
		return
	}

	// 获取子账号信息
	subAccount, err := c.accountService.GetSubAccount(subID)
	if err != nil {
		common.Error(ctx, http.StatusNotFound, "sub_account_not_found", err)
		return
	}

	// 验证是否是当前用户的主账号
	masterAccount, err := c.accountService.GetMasterAccount(userID)
	if err != nil {
		common.Error(ctx, http.StatusNotFound, "master_account_not_found", err)
		return
	}

	if subAccount.MasterAccountID != masterAccount.ID {
		common.Error(ctx, http.StatusForbidden, "forbidden", nil)
		return
	}

	// 获取分页参数
	page, pageSize := common.GetPaginationParams(ctx)

	// 获取消费记录
	records, total, err := c.accountService.GetSubAccountConsumeRecords(subID, int(page), int(pageSize))
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_consume_records_failed", err)
		return
	}

	common.Success(ctx, gin.H{
		"total": total,
		"data":  records,
	})
}

// GetSubAccountsWithConditions 根据条件查询子账号
func (c *AccountController) GetSubAccountsWithConditions(ctx *gin.Context) {
	masterAccount, ok := c.getAndValidateMasterAccount(ctx)
	if !ok {
		return
	}

	// 解析查询参数
	var req struct {
		Username    string `form:"username"`
		Role        string `form:"role"`
		Status      string `form:"status"`
		Permissions string `form:"permissions"`
		Page        int    `form:"pageIndex,default=1"`
		PageSize    int    `form:"pageSize,default=10"`
	}

	if err := ctx.ShouldBindQuery(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_params", err)
		return
	}

	// 验证分页参数
	if req.Page < 1 {
		req.Page = 1
	}
	if req.PageSize < 1 || req.PageSize > 100 {
		req.PageSize = 10
	}

	// 构建查询条件
	conditions := make(map[string]interface{})
	if req.Username != "" {
		conditions["username"] = req.Username
	}
	if req.Role != "" {
		conditions["role"] = req.Role
	}
	if req.Status != "" {
		conditions["status"] = req.Status
	}
	if req.Permissions != "" {
		conditions["permissions"] = req.Permissions
	}

	// 调用服务方法
	subAccounts, total, err := c.accountService.GetSubAccountsWithConditions(masterAccount.ID, conditions, req.Page, req.PageSize)
	if err != nil {
		if strings.Contains(err.Error(), "master_account_not_found") {
			common.Error(ctx, http.StatusNotFound, "master_account_not_found", err)
		} else {
			common.Error(ctx, http.StatusInternalServerError, "error", err)
		}
		return
	}

	// 计算分页信息
	totalPages := (total + int64(req.PageSize) - 1) / int64(req.PageSize)

	common.Success(ctx, gin.H{
		"list":        subAccounts,
		"total":       total,
		"page":        req.Page,
		"page_size":   req.PageSize,
		"total_pages": totalPages,
	})
}
